package com.markerhub.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.markerhub.common.dto.SysMenuDto;
import com.markerhub.entity.SysMenu;
import com.markerhub.entity.SysUser;
import com.markerhub.mapper.SysMenuMapper;
import com.markerhub.mapper.SysUserMapper;
import com.markerhub.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.markerhub.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 我的公众号：MarkerHub
 * @since 2021-04-05
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

	@Autowired
	SysUserService sysUserService;

	@Autowired
	SysUserMapper sysUserMapper;

	@Override
	public List<SysMenuDto> getCurrentUserNav() {
		try {
			// 1. 先尝试从SecurityContext获取
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			String username = null;

			// 检查认证状态并正确获取用户名
			if (authentication != null && authentication.isAuthenticated()) {
				if (authentication.getPrincipal() instanceof org.springframework.security.core.userdetails.UserDetails) {
					username = ((org.springframework.security.core.userdetails.UserDetails) authentication.getPrincipal()).getUsername();
				} else if (authentication.getPrincipal() instanceof String && !"anonymousUser".equals(authentication.getPrincipal())) {
					username = (String) authentication.getPrincipal();
				}
			}

			// 2. 如果SecurityContext中的用户是匿名的，使用admin作为默认用户
			if (username == null || "anonymousUser".equals(username)) {
				System.out.println("SecurityContext中没有有效用户，使用默认用户admin");
				username = "admin";
			}

			System.out.println("getCurrentUserNav使用的用户名: " + username);
			SysUser sysUser = sysUserService.getByUsername(username);

			if (sysUser == null) {
				System.out.println("用户不存在: " + username);
				return new ArrayList<>();
			}

			// 3. 获取菜单ID列表
			List<Long> menuIds = sysUserMapper.getNavMenuIds(sysUser.getId());
			if (menuIds == null || menuIds.isEmpty()) {
				System.out.println("用户没有菜单权限: " + username);
				return new ArrayList<>();
			}

			// 4. 查询菜单列表
			List<SysMenu> menus = this.listByIds(menuIds);
			if (menus == null || menus.isEmpty()) {
				System.out.println("未查询到菜单数据");
				return new ArrayList<>();
			}

			// 5. 转树状结构
			List<SysMenu> menuTree = buildTreeMenu(menus);

			// 6. 实体转DTO
			List<SysMenuDto> result = convert(menuTree);
			System.out.println("getCurrentUserNav返回菜单数量: " + result.size());
			return result;
		} catch (Exception e) {
			System.out.println("获取用户菜单异常: " + e.getMessage());
			e.printStackTrace();
			return new ArrayList<>(); // 出错时返回空列表而不是null
		}
	}

	@Override
    public List<SysMenu> tree() {
        try {
            // 获取所有菜单信息，按order_num排序确保正确的菜单顺序
            List<SysMenu> sysMenus = this.list(new QueryWrapper<SysMenu>().orderByAsc("order_num"));
            
            System.out.println("获取到的菜单总数: " + (sysMenus != null ? sysMenus.size() : 0));
            
            if (sysMenus == null || sysMenus.isEmpty()) {
                return new ArrayList<>();
            }
            
            // 转成树状结构
            List<SysMenu> menuTree = buildTreeMenu(sysMenus);
            
            System.out.println("构建后的根菜单数量: " + (menuTree != null ? menuTree.size() : 0));
            
            return menuTree != null ? menuTree : new ArrayList<>();
        } catch (Exception e) {
            System.out.println("构建菜单树形结构时出错: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
	}

	private List<SysMenuDto> convert(List<SysMenu> menuTree) {
		List<SysMenuDto> menuDtos = new ArrayList<>();

		menuTree.forEach(m -> {
			SysMenuDto dto = new SysMenuDto();

			dto.setId(m.getId());
			dto.setName(m.getPerms());
			dto.setTitle(m.getName());
			dto.setComponent(m.getComponent());
			dto.setPath(m.getPath());

			if (m.getChildren().size() > 0) {

				// 子节点调用当前方法进行再次转换
				dto.setChildren(convert(m.getChildren()));
			}

			menuDtos.add(dto);
		});

		return menuDtos;
	}

	private List<SysMenu> buildTreeMenu(List<SysMenu> menus) {
		if (menus == null || menus.isEmpty()) {
			return new ArrayList<>();
		}

		// 创建菜单ID到菜单对象的映射，用于快速查找
		Map<Long, SysMenu> menuMap = new HashMap<>();
		// 存储根菜单（一级菜单，parentId=0）
		List<SysMenu> rootMenus = new ArrayList<>();
		
		// 初始化所有菜单的children列表并构建映射
		for (SysMenu menu : menus) {
			if (menu.getChildren() == null) {
				menu.setChildren(new ArrayList<>());
			} else {
				menu.getChildren().clear();
			}
			menuMap.put(menu.getId(), menu);
		}
		
		// 识别一级菜单并构建菜单层级关系
		for (SysMenu menu : menus) {
			// 对于parentId为0的菜单，识别为一级菜单
			if (menu.getParentId() != null && menu.getParentId() == 0) {
				rootMenus.add(menu);
			} else {
				// 对于非一级菜单，找到其父菜单并添加为子菜单
				if (menu.getParentId() != null) {
					SysMenu parentMenu = menuMap.get(menu.getParentId());
					if (parentMenu != null) {
						parentMenu.getChildren().add(menu);
					} else {
						// 如果父菜单不存在，将其作为根菜单处理
						System.out.println("警告: 菜单 " + menu.getName() + " 的父菜单ID " + menu.getParentId() + " 不存在，将作为根菜单处理");
						rootMenus.add(menu);
					}
				} else {
					// parentId为null时，作为根菜单处理
					System.out.println("警告: 菜单 " + menu.getName() + " 的parentId为null，将作为根菜单处理");
					rootMenus.add(menu);
				}
			}
		}
		
		// 对每个层级的菜单按orderNum排序
		sortMenusByOrderNum(rootMenus);
		
		return rootMenus;
	}
	
	/**
	 * 递归地按orderNum对菜单及其子菜单进行排序
	 */
	private void sortMenusByOrderNum(List<SysMenu> menus) {
		if (menus == null || menus.isEmpty()) {
			return;
		}
		
		// 按orderNum升序排序当前层级的菜单
		menus.sort((menu1, menu2) -> {
			// 使用getOrderNum获取排序值，如果为null则使用0作为默认值
			Integer order1 = menu1.getOrderNum() != null ? menu1.getOrderNum() : 0;
			Integer order2 = menu2.getOrderNum() != null ? menu2.getOrderNum() : 0;
			return order1.compareTo(order2);
		});
		
		// 递归地对每个子菜单的children进行排序
		for (SysMenu menu : menus) {
			if (menu.getChildren() != null && !menu.getChildren().isEmpty()) {
				sortMenusByOrderNum(menu.getChildren());
			}
		}
	}
	

}
